package com.gitee.wsl.compose.ui.portal

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import com.gitee.wsl.compose.ui.portal.bean.KeyedPortal

@Immutable
interface ComposePortal<KeyT> : KeyedPortal<KeyT> {
  @Composable
  fun Render()
}


/**
 *
 * private val portalManager = ComposePortalManager<PortalKey>(
 *   defaultTransitionProvider = object : SimplePortalTransitionProvider {
 *     override val enterTransition = slideInHorizontally(
 *       animationSpec = tween(1000),
 *       initialOffsetX = { it * 2 },
 *     )
 *
 *     override val exitTransition = slideOutHorizontally(
 *       animationSpec = tween(1000),
 *       targetOffsetX = { it * 2 },
 *     )
 *
 *     override val backstackPushDetachTransition = fadeOut(
 *       animationSpec = tween(1000),
 *     )
 *   },
 * )
 *
 * @Composable
 * fun SimplePortal() {
 *   LaunchedEffect(Unit) {
 *     delay(500)
 *
 *     portalManager.addTenNumberBoxPortals()
 *
 *     delay(2500)
 *
 *     portalManager.withTransaction {
 *       val initialWaveDuration = 3000
 *       val secondWaveDuration = 6000
 *       val lastWaveDuration = 8000
 *
 *       backstack.clear(
 *         exitTransitionOverride = { key ->
 *           when(key) {
 *             PortalKey.One -> exitTransitionOverride {
 *               fadeOut(
 *                 animationSpec = tween(durationMillis = lastWaveDuration),
 *               )
 *             }
 *
 *             PortalKey.Two -> exitTransitionOverride {
 *               shrinkOut(
 *                 animationSpec = tween(durationMillis = lastWaveDuration),
 *               )
 *             }
 *
 *             PortalKey.Three -> exitTransitionOverride {
 *               slideOutVertically(
 *                 animationSpec = tween(durationMillis = secondWaveDuration),
 *                 targetOffsetY = { -it },
 *               )
 *             }
 *
 *             PortalKey.Four -> exitTransitionOverride {
 *               slideOutVertically(
 *                 animationSpec = tween(durationMillis = secondWaveDuration),
 *                 targetOffsetY = { it * 2 },
 *               )
 *             }
 *
 *             PortalKey.Five -> exitTransitionOverride {
 *               slideOutHorizontally(
 *                 animationSpec = tween(durationMillis = secondWaveDuration),
 *                 targetOffsetX = { -it },
 *               )
 *             }
 *
 *             PortalKey.Six -> exitTransitionOverride {
 *               slideOutHorizontally(
 *                 animationSpec = tween(durationMillis = secondWaveDuration),
 *                 targetOffsetX = { it * 2 },
 *               )
 *             }
 *
 *             PortalKey.Seven -> exitTransitionOverride {
 *               slideOutVertically(
 *                 animationSpec = tween(durationMillis = initialWaveDuration),
 *                 targetOffsetY = { -it },
 *               )
 *             }
 *
 *             PortalKey.Eight -> exitTransitionOverride {
 *               slideOutVertically(
 *                 animationSpec = tween(durationMillis = initialWaveDuration),
 *                 targetOffsetY = { it * 2 },
 *               )
 *             }
 *
 *             PortalKey.Nine -> exitTransitionOverride {
 *               slideOutHorizontally(
 *                 animationSpec = tween(durationMillis = initialWaveDuration),
 *                 targetOffsetX = { -it },
 *               )
 *             }
 *
 *             PortalKey.Ten -> exitTransitionOverride {
 *               slideOutHorizontally(
 *                 animationSpec = tween(durationMillis = initialWaveDuration),
 *                 targetOffsetX = { it * 2 },
 *               )
 *             }
 *           }
 *         },
 *       )
 *     }
 *   }
 *
 *   MaterialTheme(
 *     colorScheme = darkColorScheme(
 *       primary = Color(0xFFBB86FC),
 *       secondary = Color(0xFF03DAC5),
 *       tertiary = Color(0xFF3700B3),
 *     ),
 *   ) {
 *     Surface(
 *       modifier = Modifier.fillMaxSize(),
 *     ) {
 *       Box {
 *         portalManager.Render()
 *       }
 *     }
 *   }
 * }
 *
 * suspend fun ComposePortalManager<PortalKey>.addTenNumberBoxPortals() {
 *   suspend fun ComposePortalManager<PortalKey>.addNumberBoxPortal(
 *     previousKey: PortalKey?,
 *     key: PortalKey,
 *   ) {
 *     withTransaction {
 *       backstack.push(key) {
 *         if(previousKey != null) detachFromComposition(previousKey)
 *
 *         add(
 *           portal = NumberBoxPortal(key),
 *         )
 *       }
 *     }
 *
 *     delay(1_000L)
 *   }
 *
 *   PortalKey
 *     .entries
 *     .scan<PortalKey, PortalKey?>(null) { previous, current ->
 *       addNumberBoxPortal(previous, current)
 *       current
 *     }
 * }
 */